﻿namespace UnityEditor
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using UnityEditorInternal;
    using UnityEngine;

    [CustomEditor(typeof(AnimationClip))]
    internal class AnimationClipEditor : Editor
    {
        private static GUIContent addKeyframeContent = EditorGUIUtility.IconContent("Animation.AddKeyframe");
        private const int kHeight = 2;
        private const int kPose = 0;
        private const int kPosition = 3;
        private const int kRotation = 1;
        private const int kSamplesPerSecond = 60;
        private AvatarPreview m_AvatarPreview;
        private AvatarBodyMask m_BodyMask;
        private AvatarBodyMaskInspector m_BodyMaskInspector;
        private AnimationClip m_Clip;
        private AnimationClipInfoProperties m_ClipInfo;
        private AnimatorController m_Controller;
        private bool m_DirtyQualityCurves;
        private bool m_DraggingRange;
        private bool m_DraggingRangeBegin;
        private bool m_DraggingRangeEnd;
        private bool m_LoopBlend;
        private bool m_LoopBlendOrientation;
        private bool m_LoopBlendPositionXZ;
        private bool m_LoopBlendPositionY;
        private Vector2[][][] m_QualityCurves = new Vector2[4][][];
        private string[] m_ReferenceTransformPaths;
        private bool m_ShowBodyMask;
        private bool m_ShowCurves;
        private bool m_ShowSkeletonMask;
        private AvatarSkeletonMask m_SkeletonMask;
        private AvatarSkeletonMaskInspector m_SkeletonMaskInspector;
        private float m_StartFrame;
        private UnityEditorInternal.State m_State;
        private StateMachine m_StateMachine;
        private float m_StopFrame = 1f;
        private TimeArea m_TimeArea;
        private static GUIContent nextKeyContent = EditorGUIUtility.IconContent("Animation.NextKey");
        private static GUIContent prevKeyContent = EditorGUIUtility.IconContent("Animation.PrevKey");
        private static GUIContent s_GreenLightIcon = EditorGUIUtility.IconContent("lightMeter/greenLight");
        private static GUIContent s_LightRimIcon = EditorGUIUtility.IconContent("lightMeter/lightRim");
        private static int s_LoopMeterHint = s_LoopMeterStr.GetHashCode();
        private static string s_LoopMeterStr = "LoopMeter";
        private static int s_LoopOrientationMeterHint = s_LoopOrientationMeterStr.GetHashCode();
        private static string s_LoopOrientationMeterStr = "LoopOrientationMeter";
        private static int s_LoopPositionXZMeterHint = s_LoopPositionXZMeterStr.GetHashCode();
        private static string s_LoopPositionXZMeterStr = "LoopPostionXZMeter";
        private static int s_LoopPositionYMeterHint = s_LoopPositionYMeterStr.GetHashCode();
        private static string s_LoopPositionYMeterStr = "LoopPostionYMeter";
        private static GUIContent s_OrangeLightIcon = EditorGUIUtility.IconContent("lightMeter/orangeLight");
        private static GUIContent s_RedLightIcon = EditorGUIUtility.IconContent("lightMeter/redLight");

        private void AnimationClipGUI()
        {
            if (this.m_ClipInfo != null)
            {
                float firstFrame = this.m_ClipInfo.firstFrame;
                float lastFrame = this.m_ClipInfo.lastFrame;
                bool changedStart = false;
                bool changedStop = false;
                this.ClipRangeGUI(ref firstFrame, ref lastFrame, out changedStart, out changedStop);
                if (changedStart)
                {
                    this.m_ClipInfo.firstFrame = firstFrame;
                }
                if (changedStop)
                {
                    this.m_ClipInfo.lastFrame = lastFrame;
                }
                this.m_AvatarPreview.timeControl.startTime = firstFrame / this.m_Clip.frameRate;
                this.m_AvatarPreview.timeControl.stopTime = lastFrame / this.m_Clip.frameRate;
            }
            else
            {
                this.m_AvatarPreview.timeControl.startTime = 0f;
                this.m_AvatarPreview.timeControl.stopTime = this.m_Clip.length;
            }
            EditorGUIUtility.LookLikeControls();
            if (this.m_ClipInfo != null)
            {
                this.m_ClipInfo.loop = EditorGUILayout.Toggle("Add Loop Frame", this.m_ClipInfo.loop, new GUILayoutOption[0]);
            }
            EditorGUI.BeginChangeCheck();
            int num3 = (this.m_ClipInfo == null) ? ((int) this.m_Clip.wrapMode) : this.m_ClipInfo.wrapMode;
            num3 = (int) ((WrapModeFixed) EditorGUILayout.EnumPopup("Wrap Mode", (WrapModeFixed) num3, new GUILayoutOption[0]));
            if (EditorGUI.EndChangeCheck())
            {
                if (this.m_ClipInfo != null)
                {
                    this.m_ClipInfo.wrapMode = num3;
                }
                else
                {
                    this.m_Clip.wrapMode = (WrapMode) num3;
                }
            }
        }

        private void CalculateQualityCurves()
        {
            for (int i = 0; i < 4; i++)
            {
                this.m_QualityCurves[i] = new Vector2[2][];
            }
            for (int j = 0; j < 2; j++)
            {
                float num3 = Mathf.Max(this.m_ClipInfo.firstFrame / this.m_Clip.frameRate, this.m_Clip.startTime);
                float num4 = Mathf.Min(this.m_ClipInfo.lastFrame / this.m_Clip.frameRate, this.m_Clip.stopTime);
                float num5 = (j != 0) ? num3 : num4;
                float num6 = (j != 0) ? num3 : 0f;
                float num7 = (j != 0) ? this.m_Clip.length : num4;
                int num8 = Mathf.FloorToInt(num6 * 60f);
                int num9 = Mathf.CeilToInt(num7 * 60f);
                this.m_QualityCurves[0][j] = new Vector2[(num9 - num8) + 1];
                this.m_QualityCurves[1][j] = new Vector2[(num9 - num8) + 1];
                this.m_QualityCurves[2][j] = new Vector2[(num9 - num8) + 1];
                this.m_QualityCurves[3][j] = new Vector2[(num9 - num8) + 1];
                QualityCurvesTime time = new QualityCurvesTime {
                    fixedTime = num5,
                    variableEndStart = num6,
                    variableEndEnd = num7,
                    q = j
                };
                MuscleClipEditorUtilities.CalculateQualityCurves(this.m_Clip, time, this.m_QualityCurves[0][j], this.m_QualityCurves[1][j], this.m_QualityCurves[2][j], this.m_QualityCurves[3][j]);
            }
            this.m_DirtyQualityCurves = false;
        }

        public void ClipRangeGUI(ref float startFrame, ref float stopFrame, out bool changedStart, out bool changedStop)
        {
            changedStart = false;
            changedStop = false;
            this.m_DraggingRangeBegin = false;
            this.m_DraggingRangeEnd = false;
            bool disabled = ((((startFrame + 0.01f) < (this.m_Clip.startTime * this.m_Clip.frameRate)) || ((startFrame - 0.01f) > (this.m_Clip.stopTime * this.m_Clip.frameRate))) || ((stopFrame + 0.01f) < (this.m_Clip.startTime * this.m_Clip.frameRate))) || ((stopFrame - 0.01f) > (this.m_Clip.stopTime * this.m_Clip.frameRate));
            bool flag2 = false;
            if (disabled)
            {
                GUILayout.BeginHorizontal(EditorStyles.helpBox, new GUILayoutOption[0]);
                GUILayout.Label("The clip range is outside of the range of the source take.", EditorStyles.wordWrappedMiniLabel, new GUILayoutOption[0]);
                GUILayout.FlexibleSpace();
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayout.Space(5f);
                if (GUILayout.Button("Clamp Range", new GUILayoutOption[0]))
                {
                    flag2 = true;
                }
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
            }
            Rect position = GUILayoutUtility.GetRect((float) 10f, (float) 33f);
            position.xMin += 5f;
            position.xMax -= 4f;
            GUI.Label(position, string.Empty, "TE Toolbar");
            if (Event.current.type == EventType.Repaint)
            {
                this.m_TimeArea.rect = position;
            }
            this.m_TimeArea.BeginViewGUI();
            this.m_TimeArea.EndViewGUI();
            position.height -= 15f;
            int controlID = GUIUtility.GetControlID(0x2fb605, FocusType.Passive);
            int id = GUIUtility.GetControlID(0x2fb605, FocusType.Passive);
            GUI.BeginGroup(new Rect(position.x + 1f, position.y + 1f, position.width - 2f, position.height - 2f));
            float num8 = -1f;
            position.y = num8;
            position.x = num8;
            float left = this.m_TimeArea.FrameToPixel(startFrame, this.m_Clip.frameRate, position);
            float num4 = this.m_TimeArea.FrameToPixel(stopFrame, this.m_Clip.frameRate, position);
            GUI.Label(new Rect(left, position.y, num4 - left, position.height), string.Empty, EditorStyles.selectionRect);
            this.m_TimeArea.TimeRuler(position, this.m_Clip.frameRate);
            float x = this.m_TimeArea.TimeToPixel(this.m_AvatarPreview.timeControl.currentTime, position) - 0.5f;
            Handles.color = new Color(1f, 0f, 0f, 0.5f);
            Handles.DrawLine((Vector3) new Vector2(x, position.yMin), (Vector3) new Vector2(x, position.yMax));
            Handles.DrawLine((Vector3) new Vector2(x + 1f, position.yMin), (Vector3) new Vector2(x + 1f, position.yMax));
            Handles.color = Color.white;
            EditorGUI.BeginDisabledGroup(disabled);
            float time = startFrame / this.m_Clip.frameRate;
            if (this.m_TimeArea.BrowseRuler(position, controlID, ref time, 0f, false, "TL InPoint") != TimeArea.TimeRulerDragMode.None)
            {
                startFrame = time * this.m_Clip.frameRate;
                startFrame = MathUtils.RoundBasedOnMinimumDifference(startFrame, (this.m_TimeArea.PixelDeltaToTime(position) * this.m_Clip.frameRate) * 10f);
                changedStart = true;
            }
            float num7 = stopFrame / this.m_Clip.frameRate;
            if (this.m_TimeArea.BrowseRuler(position, id, ref num7, 0f, false, "TL OutPoint") != TimeArea.TimeRulerDragMode.None)
            {
                stopFrame = num7 * this.m_Clip.frameRate;
                stopFrame = MathUtils.RoundBasedOnMinimumDifference(stopFrame, (this.m_TimeArea.PixelDeltaToTime(position) * this.m_Clip.frameRate) * 10f);
                changedStop = true;
            }
            EditorGUI.EndDisabledGroup();
            if (GUIUtility.hotControl == controlID)
            {
                changedStart = true;
            }
            if (GUIUtility.hotControl == id)
            {
                changedStop = true;
            }
            GUI.EndGroup();
            EditorGUI.BeginDisabledGroup(disabled);
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            EditorGUI.BeginChangeCheck();
            startFrame = EditorGUILayout.FloatField("Start", startFrame, new GUILayoutOption[0]);
            if (EditorGUI.EndChangeCheck())
            {
                changedStart = true;
            }
            GUILayout.FlexibleSpace();
            EditorGUI.BeginChangeCheck();
            stopFrame = EditorGUILayout.FloatField("End", stopFrame, new GUILayoutOption[0]);
            if (EditorGUI.EndChangeCheck())
            {
                changedStop = true;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUI.EndDisabledGroup();
            changedStart |= flag2;
            changedStop |= flag2;
            if (changedStart)
            {
                startFrame = Mathf.Clamp(startFrame, this.m_Clip.startTime * this.m_Clip.frameRate, stopFrame - 0.1f);
            }
            if (changedStop)
            {
                stopFrame = Mathf.Clamp(stopFrame, startFrame + 0.1f, this.m_Clip.stopTime * this.m_Clip.frameRate);
            }
            if (changedStart || changedStop)
            {
                if (!this.m_DraggingRange)
                {
                    this.m_DraggingRangeBegin = true;
                }
                this.m_DraggingRange = true;
            }
            else if ((this.m_DraggingRange && (GUIUtility.hotControl == 0)) && (Event.current.type == EventType.Repaint))
            {
                this.m_DraggingRangeEnd = true;
                this.m_DraggingRange = false;
                this.m_DirtyQualityCurves = true;
                base.Repaint();
            }
            GUILayout.Space(10f);
        }

        private void CurveGUI()
        {
            if (this.m_ClipInfo != null)
            {
                float normalizedTime = this.m_AvatarPreview.timeControl.normalizedTime;
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                for (int i = 0; i < this.m_ClipInfo.GetCurveCount(); i++)
                {
                    GUILayout.Space(5f);
                    GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                    GUILayoutOption[] optionArray1 = new GUILayoutOption[] { GUILayout.Width(17f) };
                    if (GUILayout.Button(GUIContent.none, "OL Minus", optionArray1))
                    {
                        this.m_ClipInfo.RemoveCurve(i);
                    }
                    else
                    {
                        GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Width(125f) };
                        GUILayout.BeginVertical(optionArray2);
                        string curveName = this.m_ClipInfo.GetCurveName(i);
                        string name = EditorGUILayout.DelayedTextField(curveName, null, EditorStyles.textField, new GUILayoutOption[0]);
                        if (curveName != name)
                        {
                            this.m_ClipInfo.SetCurveName(i, name);
                        }
                        AnimationCurve curve = this.m_ClipInfo.GetCurve(i);
                        int length = curve.length;
                        bool disabled = false;
                        int index = length - 1;
                        for (int j = 0; j < length; j++)
                        {
                            if (Mathf.Abs((float) (curve.keys[j].time - normalizedTime)) < 0.0001f)
                            {
                                disabled = true;
                                index = j;
                                break;
                            }
                            if (curve.keys[j].time > normalizedTime)
                            {
                                index = j;
                                break;
                            }
                        }
                        GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                        if (GUILayout.Button(prevKeyContent, new GUILayoutOption[0]) && (index > 0))
                        {
                            index--;
                            this.m_AvatarPreview.timeControl.normalizedTime = curve.keys[index].time;
                        }
                        if (GUILayout.Button(nextKeyContent, new GUILayoutOption[0]))
                        {
                            if (disabled && (index < (length - 1)))
                            {
                                index++;
                            }
                            this.m_AvatarPreview.timeControl.normalizedTime = curve.keys[index].time;
                        }
                        EditorGUI.BeginDisabledGroup(!disabled);
                        string kFloatFieldFormatString = EditorGUI.kFloatFieldFormatString;
                        EditorGUI.kFloatFieldFormatString = "n3";
                        float num6 = curve.Evaluate(normalizedTime);
                        GUILayoutOption[] optionArray3 = new GUILayoutOption[] { GUILayout.Width(60f) };
                        float num7 = EditorGUILayout.FloatField(num6, optionArray3);
                        EditorGUI.kFloatFieldFormatString = kFloatFieldFormatString;
                        EditorGUI.EndDisabledGroup();
                        bool flag2 = false;
                        if (num6 != num7)
                        {
                            if (disabled)
                            {
                                curve.RemoveKey(index);
                            }
                            flag2 = true;
                        }
                        EditorGUI.BeginDisabledGroup(disabled);
                        if (GUILayout.Button(addKeyframeContent, new GUILayoutOption[0]))
                        {
                            flag2 = true;
                        }
                        EditorGUI.EndDisabledGroup();
                        if (flag2)
                        {
                            Keyframe key = new Keyframe {
                                time = normalizedTime,
                                value = num7,
                                inTangent = 0f,
                                outTangent = 0f
                            };
                            curve.AddKey(key);
                        }
                        GUILayout.EndHorizontal();
                        GUILayout.EndVertical();
                        GUILayoutOption[] optionArray4 = new GUILayoutOption[] { GUILayout.Height(40f) };
                        curve = EditorGUILayout.CurveField(curve, optionArray4);
                        Rect lastRect = GUILayoutUtility.GetLastRect();
                        length = curve.length;
                        Handles.color = Color.red;
                        Handles.DrawLine(new Vector3(lastRect.x + (normalizedTime * lastRect.width), lastRect.y, 0f), new Vector3(lastRect.x + (normalizedTime * lastRect.width), lastRect.y + lastRect.height, 0f));
                        for (int k = 0; k < length; k++)
                        {
                            float time = curve.keys[k].time;
                            Handles.color = Color.white;
                            Handles.DrawLine(new Vector3(lastRect.x + (time * lastRect.width), (lastRect.y + lastRect.height) - 10f, 0f), new Vector3(lastRect.x + (time * lastRect.width), lastRect.y + lastRect.height, 0f));
                        }
                        this.m_ClipInfo.SetCurve(i, curve);
                        GUILayout.Space(5f);
                    }
                    GUILayout.EndHorizontal();
                }
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(17f) };
                if (GUILayout.Button(GUIContent.none, "OL Plus", options))
                {
                    this.m_ClipInfo.AddCurve();
                }
                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            }
        }

        private void DestroyController()
        {
            if ((this.m_AvatarPreview != null) && (this.m_AvatarPreview.Animator != null))
            {
                AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, null);
            }
            UnityEngine.Object.DestroyImmediate(this.m_Controller);
            UnityEngine.Object.DestroyImmediate(this.m_StateMachine);
            UnityEngine.Object.DestroyImmediate(this.m_State);
            this.m_Controller = null;
            this.m_StateMachine = null;
            this.m_State = null;
        }

        private float GetClipLength()
        {
            if (this.m_ClipInfo == null)
            {
                return this.m_Clip.length;
            }
            return ((this.m_ClipInfo.lastFrame - this.m_ClipInfo.firstFrame) / this.m_Clip.frameRate);
        }

        public override bool HasPreviewGUI()
        {
            this.Init();
            return (this.m_AvatarPreview != null);
        }

        private void Init()
        {
            if (this.m_AvatarPreview == null)
            {
                this.m_AvatarPreview = new AvatarPreview(null, base.target as Motion);
                this.m_AvatarPreview.OnAvatarChangeFunc = new AvatarPreview.OnAvatarChange(this.SetPreviewAvatar);
                this.m_AvatarPreview.fps = Mathf.RoundToInt((base.target as AnimationClip).frameRate);
                this.m_AvatarPreview.ShowIKOnFeetButton = (base.target as Motion).isHumanMotion;
            }
        }

        private void InitBodyMask()
        {
            if (this.m_BodyMask == null)
            {
                this.m_BodyMask = new AvatarBodyMask();
                this.m_BodyMaskInspector = (AvatarBodyMaskInspector) Editor.CreateEditor(this.m_BodyMask);
            }
        }

        private void InitController()
        {
            if ((this.m_AvatarPreview != null) && (this.m_AvatarPreview.Animator != null))
            {
                if (this.m_StateMachine == null)
                {
                    this.m_StateMachine = new StateMachine();
                    this.m_StateMachine.hideFlags = HideFlags.DontSave;
                }
                if (this.m_State == null)
                {
                    this.m_State = this.m_StateMachine.AddState("preview");
                    this.m_State.SetMotion(0, this.m_Clip);
                    this.m_State.SetIKOnFeet(this.m_AvatarPreview.IKOnFeet);
                    this.m_State.hideFlags = HideFlags.DontSave;
                }
                if (this.m_Controller == null)
                {
                    this.m_Controller = new AnimatorController();
                    this.m_Controller.AddLayer("preview");
                    this.m_Controller.SetLayerStateMachine(0, this.m_StateMachine);
                    if (this.m_ClipInfo != null)
                    {
                        this.InitBodyMask();
                        this.m_ClipInfo.BodyMaskFromClip(this.m_BodyMask);
                        this.m_Controller.SetLayerHumanMask(0, this.m_BodyMask);
                        this.InitSkeletonMask();
                        this.m_ClipInfo.SkeletonMaskFromClip(ref this.m_SkeletonMask);
                        this.m_Controller.SetLayerSkeletonMask(0, this.m_SkeletonMask);
                    }
                    AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, this.m_Controller);
                    this.m_Controller.hideFlags = HideFlags.DontSave;
                }
                if (AnimatorController.GetAnimatorController(this.m_AvatarPreview.Animator) != this.m_Controller)
                {
                    AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, this.m_Controller);
                }
            }
        }

        private void InitSkeletonMask()
        {
            if (this.m_SkeletonMask == null)
            {
                this.m_SkeletonMask = new AvatarSkeletonMask();
                this.m_SkeletonMaskInspector = (AvatarSkeletonMaskInspector) Editor.CreateEditor(this.m_SkeletonMask);
                this.m_SkeletonMaskInspector.canImport = false;
            }
        }

        private void LoopQualityLampAndCurve(Rect position, float value, int lightMeterHint, bool changedStart, bool changedStop, Vector2[][] curves)
        {
            if (this.m_ClipInfo != null)
            {
                GUIStyle style = new GUIStyle(EditorStyles.miniLabel) {
                    alignment = TextAnchor.MiddleRight
                };
                Rect rect = position;
                rect.xMax -= 20f;
                rect.xMin += EditorGUIUtility.labelWidth;
                GUI.Label(rect, "loop match", style);
                Event current = Event.current;
                int controlID = GUIUtility.GetControlID(lightMeterHint, FocusType.Native, position);
                if (current.GetTypeForControl(controlID) == EventType.Repaint)
                {
                    Rect rect2 = position;
                    float num3 = (22f - rect2.height) / 2f;
                    rect2.y -= num3;
                    rect2.xMax += num3;
                    rect2.height = 22f;
                    rect2.xMin = rect2.xMax - 22f;
                    if (value < 0.33f)
                    {
                        GUI.DrawTexture(rect2, s_RedLightIcon.image);
                    }
                    else if (value < 0.66f)
                    {
                        GUI.DrawTexture(rect2, s_OrangeLightIcon.image);
                    }
                    else
                    {
                        GUI.DrawTexture(rect2, s_GreenLightIcon.image);
                    }
                    GUI.DrawTexture(rect2, s_LightRimIcon.image);
                }
                if (changedStart || changedStop)
                {
                    Rect rect3 = position;
                    rect3.y += rect3.height + 1f;
                    rect3.height = 18f;
                    GUI.color = new Color(0f, 0f, 0f, (EditorGUIUtility.skinIndex != 0) ? 0.3f : 0.8f);
                    GUI.DrawTexture(rect3, EditorGUIUtility.whiteTexture);
                    rect3 = new RectOffset(-1, -1, -1, -1).Add(rect3);
                    if (EditorGUIUtility.skinIndex == 0)
                    {
                        GUI.color = new Color(0.3529412f, 0.3529412f, 0.3529412f, 1f);
                    }
                    else
                    {
                        GUI.color = new Color(0.254902f, 0.254902f, 0.254902f, 1f);
                    }
                    GUI.DrawTexture(rect3, EditorGUIUtility.whiteTexture);
                    GUI.color = Color.white;
                    GUI.BeginGroup(rect3);
                    Matrix4x4 drawingToViewMatrix = this.m_TimeArea.drawingToViewMatrix;
                    drawingToViewMatrix.m00 = rect3.width / this.m_TimeArea.shownArea.width;
                    drawingToViewMatrix.m11 = rect3.height - 1f;
                    drawingToViewMatrix.m03 = (-this.m_TimeArea.shownArea.x * rect3.width) / this.m_TimeArea.shownArea.width;
                    drawingToViewMatrix.m13 = 0f;
                    Vector2[] vectorArray = curves[!changedStart ? 1 : 0];
                    Vector3[] points = new Vector3[vectorArray.Length];
                    Color[] colors = new Color[vectorArray.Length];
                    Color color = new Color(1f, 0.3f, 0.3f);
                    Color color2 = new Color(1f, 0.8f, 0f);
                    Color color3 = new Color(0f, 1f, 0f);
                    for (int i = 0; i < points.Length; i++)
                    {
                        points[i] = (Vector3) vectorArray[i];
                        points[i] = drawingToViewMatrix.MultiplyPoint3x4(points[i]);
                        if ((1f - vectorArray[i].y) < 0.33f)
                        {
                            colors[i] = color;
                        }
                        else if ((1f - vectorArray[i].y) < 0.66f)
                        {
                            colors[i] = color2;
                        }
                        else
                        {
                            colors[i] = color3;
                        }
                    }
                    Handles.DrawAAPolyLine(colors, points);
                    GUI.color = new Color(0.3f, 0.6f, 1f);
                    GUI.DrawTexture(new Rect(drawingToViewMatrix.MultiplyPoint3x4(new Vector3((!changedStart ? this.m_StopFrame : this.m_StartFrame) / this.m_Clip.frameRate, 0f, 0f)).x, 0f, 1f, rect3.height), EditorGUIUtility.whiteTexture);
                    GUI.DrawTexture(new Rect(drawingToViewMatrix.MultiplyPoint3x4(new Vector3((!changedStart ? this.m_StartFrame : this.m_StopFrame) / this.m_Clip.frameRate, 0f, 0f)).x, 0f, 1f, rect3.height), EditorGUIUtility.whiteTexture);
                    GUI.color = Color.white;
                    GUI.EndGroup();
                }
            }
        }

        private void LoopToggle(Rect r, string label, ref bool val)
        {
            if (!this.m_DraggingRange)
            {
                val = EditorGUI.Toggle(r, label, val);
            }
            else
            {
                EditorGUI.LabelField(r, label, string.Empty);
                EditorGUI.BeginDisabledGroup(true);
                EditorGUI.Toggle(r, " ", false);
                EditorGUI.EndDisabledGroup();
            }
        }

        private void MuscleClipGUI()
        {
            bool changed;
            EditorGUI.BeginChangeCheck();
            this.InitController();
            MuscleClipInfo muscleClipInfo = MuscleClipEditorUtilities.GetMuscleClipInfo(this.m_Clip);
            bool isHumanMotion = (base.target as Motion).isHumanMotion;
            this.m_StartFrame = !this.m_DraggingRange ? (muscleClipInfo.startTime * this.m_Clip.frameRate) : this.m_StartFrame;
            this.m_StopFrame = !this.m_DraggingRange ? (muscleClipInfo.stopTime * this.m_Clip.frameRate) : this.m_StopFrame;
            bool changedStart = false;
            bool changedStop = false;
            if (this.m_ClipInfo != null)
            {
                if (isHumanMotion)
                {
                    if (this.m_DirtyQualityCurves)
                    {
                        this.CalculateQualityCurves();
                    }
                    if ((this.m_QualityCurves[0] == null) && (Event.current.type == EventType.Repaint))
                    {
                        this.m_DirtyQualityCurves = true;
                        base.Repaint();
                    }
                }
                this.ClipRangeGUI(ref this.m_StartFrame, ref this.m_StopFrame, out changedStart, out changedStop);
            }
            float startTime = this.m_StartFrame / this.m_Clip.frameRate;
            float stopTime = this.m_StopFrame / this.m_Clip.frameRate;
            if (!this.m_DraggingRange)
            {
                muscleClipInfo.startTime = startTime;
                muscleClipInfo.stopTime = stopTime;
            }
            this.m_AvatarPreview.timeControl.startTime = startTime;
            this.m_AvatarPreview.timeControl.stopTime = stopTime;
            if (changedStart)
            {
                this.m_AvatarPreview.timeControl.nextCurrentTime = startTime;
            }
            if (changedStop)
            {
                this.m_AvatarPreview.timeControl.nextCurrentTime = stopTime;
            }
            EditorGUIUtility.LookLikeControls();
            MuscleClipQualityInfo info2 = MuscleClipEditorUtilities.GetMuscleClipQualityInfo(this.m_Clip, startTime, stopTime);
            Rect controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            this.LoopToggle(controlRect, "Loop Pose", ref muscleClipInfo.loopBlend);
            EditorGUI.BeginDisabledGroup(!muscleClipInfo.loopBlend);
            muscleClipInfo.cycleOffset = EditorGUILayout.FloatField("Cycle Offset", muscleClipInfo.cycleOffset, new GUILayoutOption[0]);
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.Space();
            string str = "Original";
            string str2 = !isHumanMotion ? "Root Node Rotation" : "Body Orientation";
            string str3 = !isHumanMotion ? "Root Node Position" : "Center of Mass";
            bool flag4 = isHumanMotion && (changedStart || changedStop);
            GUILayout.Label("Root Transform Rotation", EditorStyles.label, new GUILayoutOption[0]);
            EditorGUI.indentLevel++;
            Rect r = EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            this.LoopToggle(r, "Bake into Pose", ref muscleClipInfo.loopBlendOrientation);
            int selectedIndex = !muscleClipInfo.keepOriginalOrientation ? 1 : 0;
            string[] displayedOptions = new string[] { str, str2 };
            selectedIndex = EditorGUILayout.Popup("Based Upon" + (!muscleClipInfo.loopBlendOrientation ? string.Empty : " (at Start)"), selectedIndex, displayedOptions, new GUILayoutOption[0]);
            muscleClipInfo.keepOriginalOrientation = selectedIndex == 0;
            if (flag4)
            {
                EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            }
            else
            {
                muscleClipInfo.orientationOffsetY = EditorGUILayout.FloatField("Offset", muscleClipInfo.orientationOffsetY, new GUILayoutOption[0]);
            }
            EditorGUI.indentLevel--;
            EditorGUILayout.Space();
            GUILayout.Label("Root Transform Position (Y)", EditorStyles.label, new GUILayoutOption[0]);
            EditorGUI.indentLevel++;
            Rect rect3 = EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            this.LoopToggle(rect3, "Bake into Pose", ref muscleClipInfo.loopBlendPositionY);
            if (isHumanMotion)
            {
                int num4;
                if (muscleClipInfo.keepOriginalPositionY)
                {
                    num4 = 0;
                }
                else if (muscleClipInfo.heightFromFeet)
                {
                    num4 = 2;
                }
                else
                {
                    num4 = 1;
                }
                string[] textArray2 = new string[] { str, str3, "Feet" };
                switch (EditorGUILayout.Popup("Based Upon" + (!muscleClipInfo.loopBlendPositionY ? string.Empty : " (at Start)"), num4, textArray2, new GUILayoutOption[0]))
                {
                    case 0:
                        muscleClipInfo.keepOriginalPositionY = true;
                        muscleClipInfo.heightFromFeet = false;
                        goto Label_0482;

                    case 1:
                        muscleClipInfo.keepOriginalPositionY = false;
                        muscleClipInfo.heightFromFeet = false;
                        goto Label_0482;
                }
                muscleClipInfo.keepOriginalPositionY = false;
                muscleClipInfo.heightFromFeet = true;
            }
            else
            {
                int num5 = !muscleClipInfo.keepOriginalPositionY ? 1 : 0;
                string[] textArray3 = new string[] { str, str3 };
                num5 = EditorGUILayout.Popup("Based Upon" + (!muscleClipInfo.loopBlendOrientation ? string.Empty : " (at Start)"), num5, textArray3, new GUILayoutOption[0]);
                muscleClipInfo.keepOriginalPositionY = num5 == 0;
            }
        Label_0482:
            if (flag4)
            {
                EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            }
            else
            {
                muscleClipInfo.level = EditorGUILayout.FloatField("Offset", muscleClipInfo.level, new GUILayoutOption[0]);
            }
            EditorGUI.indentLevel--;
            EditorGUILayout.Space();
            GUILayout.Label("Root Transform Position (XZ)", EditorStyles.label, new GUILayoutOption[0]);
            EditorGUI.indentLevel++;
            Rect rect4 = EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            this.LoopToggle(rect4, "Bake into Pose", ref muscleClipInfo.loopBlendPositionXZ);
            int num6 = !muscleClipInfo.keepOriginalPositionXZ ? 1 : 0;
            string[] textArray4 = new string[] { str, str3 };
            num6 = EditorGUILayout.Popup("Based Upon" + (!muscleClipInfo.loopBlendPositionXZ ? string.Empty : " (at Start)"), num6, textArray4, new GUILayoutOption[0]);
            muscleClipInfo.keepOriginalPositionXZ = num6 == 0;
            EditorGUI.indentLevel--;
            EditorGUILayout.Space();
            if (isHumanMotion)
            {
                this.LoopQualityLampAndCurve(controlRect, info2.loop, s_LoopMeterHint, changedStart, changedStop, this.m_QualityCurves[0]);
                this.LoopQualityLampAndCurve(r, info2.loopOrientation, s_LoopOrientationMeterHint, changedStart, changedStop, this.m_QualityCurves[1]);
                this.LoopQualityLampAndCurve(rect3, info2.loopPositionY, s_LoopPositionYMeterHint, changedStart, changedStop, this.m_QualityCurves[2]);
                this.LoopQualityLampAndCurve(rect4, info2.loopPositionXZ, s_LoopPositionXZMeterHint, changedStart, changedStop, this.m_QualityCurves[3]);
                muscleClipInfo.mirror = EditorGUILayout.Toggle("Mirror", muscleClipInfo.mirror, new GUILayoutOption[0]);
                GUILayout.Label(("Average Velocity: " + this.m_Clip.averageSpeed.ToString("0.000") + "\nAverage Angular Y Speed: ") + (((this.m_Clip.averageAngularSpeed * 180f) / 3.141593f)).ToString("0.0") + " deg/s", EditorStyles.helpBox, new GUILayoutOption[0]);
                EditorGUILayout.Space();
                if (this.m_ClipInfo != null)
                {
                    changed = GUI.changed;
                    this.m_ShowBodyMask = EditorGUILayout.Foldout(this.m_ShowBodyMask, "Body Mask");
                    GUI.changed = changed;
                    if (this.m_ShowBodyMask)
                    {
                        this.InitBodyMask();
                        this.m_ClipInfo.BodyMaskFromClip(this.m_BodyMask);
                        this.m_BodyMaskInspector.OnInspectorGUI();
                        this.m_ClipInfo.BodyMaskToClip(this.m_BodyMask);
                        muscleClipInfo.keepAdditionalBonesAnimation = EditorGUILayout.Toggle("Keep Additional Bones", muscleClipInfo.keepAdditionalBonesAnimation, new GUILayoutOption[0]);
                    }
                }
            }
            if (this.m_ClipInfo != null)
            {
                changed = GUI.changed;
                EditorGUI.BeginChangeCheck();
                this.m_ShowSkeletonMask = EditorGUILayout.Foldout(this.m_ShowSkeletonMask, "Transform Mask");
                bool flag6 = EditorGUI.EndChangeCheck();
                GUI.changed = changed;
                if (this.m_ShowSkeletonMask)
                {
                    if (flag6)
                    {
                        this.InitSkeletonMask();
                        this.m_ClipInfo.SkeletonMaskFromClip(ref this.m_SkeletonMask);
                    }
                    if ((this.m_SkeletonMask == null) || (this.m_SkeletonMask.count == 0))
                    {
                        GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(17f) };
                        if (GUILayout.Button(GUIContent.none, "OL Plus", options))
                        {
                            this.SetSkeletonMaskFromReference();
                            this.m_ClipInfo.SkeletonMaskToClip(this.m_SkeletonMask);
                        }
                    }
                    else
                    {
                        bool flag7 = false;
                        GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Width(17f) };
                        if (GUILayout.Button(GUIContent.none, "OL Minus", optionArray2))
                        {
                            this.m_SkeletonMask.count = 0;
                            flag7 = true;
                        }
                        else
                        {
                            EditorGUI.BeginChangeCheck();
                            this.m_SkeletonMaskInspector.OnInspectorGUI();
                            if (EditorGUI.EndChangeCheck())
                            {
                                flag7 = true;
                            }
                        }
                        if (flag7)
                        {
                            this.m_ClipInfo.SkeletonMaskToClip(this.m_SkeletonMask);
                        }
                    }
                }
            }
            if (InternalEditorUtility.HasPro() && (this.m_ClipInfo != null))
            {
                changed = GUI.changed;
                this.m_ShowCurves = EditorGUILayout.Foldout(this.m_ShowCurves, "Curves");
                GUI.changed = changed;
                if (this.m_ShowCurves)
                {
                    this.CurveGUI();
                }
            }
            if (this.m_DraggingRangeBegin)
            {
                this.m_LoopBlend = muscleClipInfo.loopBlend;
                this.m_LoopBlendOrientation = muscleClipInfo.loopBlendOrientation;
                this.m_LoopBlendPositionY = muscleClipInfo.loopBlendPositionY;
                this.m_LoopBlendPositionXZ = muscleClipInfo.loopBlendPositionXZ;
                muscleClipInfo.loopBlend = false;
                muscleClipInfo.loopBlendOrientation = false;
                muscleClipInfo.loopBlendPositionY = false;
                muscleClipInfo.loopBlendPositionXZ = false;
                muscleClipInfo.startTime = 0f;
                muscleClipInfo.stopTime = this.m_Clip.length;
                MuscleClipEditorUtilities.SetMuscleClipInfoNoDirty(this.m_Clip, muscleClipInfo);
                this.DestroyController();
            }
            if (this.m_DraggingRangeEnd)
            {
                muscleClipInfo.loopBlend = this.m_LoopBlend;
                muscleClipInfo.loopBlendOrientation = this.m_LoopBlendOrientation;
                muscleClipInfo.loopBlendPositionY = this.m_LoopBlendPositionY;
                muscleClipInfo.loopBlendPositionXZ = this.m_LoopBlendPositionXZ;
            }
            if ((EditorGUI.EndChangeCheck() || this.m_DraggingRangeEnd) && !this.m_DraggingRange)
            {
                Undo.RegisterUndo(this.m_Clip, "Muscle Clip Edit");
                MuscleClipEditorUtilities.SetMuscleClipInfoNoDirty(this.m_Clip, muscleClipInfo);
                EditorUtility.SetDirty(this.m_Clip);
                this.DestroyController();
            }
        }

        internal override void OnAssetStoreInspectorGUI()
        {
            this.OnInspectorGUI();
        }

        private void OnDisable()
        {
            this.DestroyController();
            if (this.m_AvatarPreview != null)
            {
                this.m_AvatarPreview.OnDestroy();
            }
            if (this.m_BodyMaskInspector != null)
            {
                UnityEngine.Object.DestroyImmediate(this.m_BodyMaskInspector);
            }
            if (this.m_BodyMask != null)
            {
                UnityEngine.Object.DestroyImmediate(this.m_BodyMask);
            }
            if (this.m_SkeletonMaskInspector != null)
            {
                UnityEngine.Object.DestroyImmediate(this.m_SkeletonMaskInspector);
            }
            if (this.m_SkeletonMask != null)
            {
                UnityEngine.Object.DestroyImmediate(this.m_SkeletonMask);
            }
        }

        private void OnEnable()
        {
            this.m_Clip = base.target as AnimationClip;
            if (this.m_TimeArea == null)
            {
                this.m_TimeArea = new TimeArea(true);
                this.m_TimeArea.hRangeLocked = false;
                this.m_TimeArea.vRangeLocked = true;
                this.m_TimeArea.hSlider = true;
                this.m_TimeArea.vSlider = false;
                this.m_TimeArea.hRangeMin = this.m_Clip.startTime;
                this.m_TimeArea.hRangeMax = this.m_Clip.stopTime;
                this.m_TimeArea.margin = 10f;
                this.m_TimeArea.scaleWithWindow = true;
                this.m_TimeArea.SetShownHRangeInsideMargins(this.m_Clip.startTime, this.m_Clip.stopTime);
                this.m_TimeArea.hTicks.SetTickModulosForFrameRate(this.m_Clip.frameRate);
                this.m_TimeArea.ignoreScrollWheelUntilClicked = true;
            }
            this.m_TimeArea.OnEnable();
        }

        internal override void OnHeaderControlsGUI()
        {
            if (((this.m_ClipInfo != null) && (this.takeNames != null)) && (this.takeNames.Length > 1))
            {
                EditorGUIUtility.LookLikeControls(80f);
                this.takeIndex = EditorGUILayout.Popup("Source Take", this.takeIndex, this.takeNames, new GUILayoutOption[0]);
            }
            else
            {
                base.OnHeaderControlsGUI();
            }
        }

        internal override void OnHeaderIconGUI(Rect iconRect)
        {
            Texture2D image = null;
            bool flag = AssetPreview.IsLoadingAssetPreview(base.target.GetInstanceID());
            image = AssetPreview.GetAssetPreview(base.target);
            if (image == null)
            {
                if (flag)
                {
                    base.Repaint();
                }
                image = AssetPreview.GetMiniThumbnail(base.target);
            }
            GUI.DrawTexture(iconRect, image);
        }

        internal override void OnHeaderTitleGUI(Rect titleRect, string header)
        {
            if (this.m_ClipInfo != null)
            {
                this.m_ClipInfo.name = EditorGUI.DelayedTextField(titleRect, this.m_ClipInfo.name, null, EditorStyles.textField);
            }
            else
            {
                base.OnHeaderTitleGUI(titleRect, header);
            }
        }

        public override void OnInspectorGUI()
        {
            this.Init();
            EditorGUIUtility.LookLikeControls(50f, 30f);
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            EditorGUI.BeginDisabledGroup(true);
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(46f) };
            GUILayout.Label("Length", EditorStyles.miniLabel, options);
            GUILayout.Label(this.GetClipLength().ToString("0.000"), EditorStyles.miniLabel, new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            GUILayout.Label(this.m_Clip.frameRate + " FPS", EditorStyles.miniLabel, new GUILayoutOption[0]);
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();
            if (this.m_Clip.isAnimatorMotion)
            {
                this.MuscleClipGUI();
            }
            else
            {
                this.AnimationClipGUI();
            }
        }

        public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
        {
            bool flag = true;
            this.InitController();
            if (flag)
            {
                this.m_AvatarPreview.timeControl.Update();
            }
            AnimationClip target = base.target as AnimationClip;
            MuscleClipInfo muscleClipInfo = MuscleClipEditorUtilities.GetMuscleClipInfo(target);
            this.m_AvatarPreview.timeControl.loop = true;
            if (flag && (this.m_AvatarPreview.PreviewObject != null))
            {
                if (this.m_AvatarPreview.Animator != null)
                {
                    if (this.m_State != null)
                    {
                        this.m_State.SetIKOnFeet(this.m_AvatarPreview.IKOnFeet);
                    }
                    this.m_AvatarPreview.Animator.ForceStateNormalizedTime((this.m_AvatarPreview.timeControl.currentTime - muscleClipInfo.startTime) / (muscleClipInfo.stopTime - muscleClipInfo.startTime));
                    this.m_AvatarPreview.Animator.Update(this.m_AvatarPreview.timeControl.deltaTime);
                }
                else
                {
                    this.m_AvatarPreview.PreviewObject.SampleAnimation(target, this.m_AvatarPreview.timeControl.currentTime);
                }
            }
            this.m_AvatarPreview.DoAvatarPreview(r, background);
        }

        public override void OnPreviewSettings()
        {
            this.m_AvatarPreview.DoPreviewSettings();
        }

        private void SetPreviewAvatar()
        {
            this.DestroyController();
            this.InitController();
        }

        private void SetSkeletonMaskFromReference()
        {
            this.m_SkeletonMask.count = this.m_ReferenceTransformPaths.Length;
            for (int i = 0; i < this.m_ReferenceTransformPaths.Length; i++)
            {
                this.m_SkeletonMask.SetPath(i, this.m_ReferenceTransformPaths[i]);
                this.m_SkeletonMask.SetWeight(i, 1f);
            }
        }

        public void ShowRange(AnimationClipInfoProperties info)
        {
            this.m_ClipInfo = info;
            info.AssignToPreviewClip(this.m_Clip);
        }

        public string[] referenceTransformPaths
        {
            get
            {
                return this.m_ReferenceTransformPaths;
            }
            set
            {
                this.m_ReferenceTransformPaths = value;
            }
        }

        public int takeIndex { get; set; }

        public string[] takeNames { get; set; }
    }
}

